<?php  if ( ! defined('__CORE_PATH__')) exit('No direct script access allowed');
/* SVN FILE: $Id: app_controller.php 25 2008-08-29 21:58:28Z namaless $ */
/**
 * File contentente le funzionalità per la gestione della versione.
 *
 * @author			Pereira Pulido Nuno Ricardo | Namaless | namaless@gmail.com
 * @copyright		Copyright 1981-2008, Namaless.
 * @link			http://www.namaless.com Namaless Blog
 * @version			1.0
 * @version			$Revision: 25 $
 * @modifiedby		$LastChangedBy: namaless $
 * @lastmodified	$Date: 2008-08-29 23:58:28 +0200 (ven, 29 ago 2008) $
 * @license			http://www.opensource.org/licenses/gpl-license.php GNU Public License
 */

/**
* Classe Principale.
*/
class User_agent
{
	var $agent		= NULL;
	
	var $is_browser	= FALSE;
	var $is_robot	= FALSE;
	var $is_mobile	= FALSE;

	var $languages	= array();
	var $charsets	= array();

	var $platforms = array (
					'windows nt 6.0'	=> 'Windows Longhorn',
					'windows nt 5.2'	=> 'Windows 2003',
					'windows nt 5.0'	=> 'Windows 2000',
					'windows nt 5.1'	=> 'Windows XP',
					'windows nt 4.0'	=> 'Windows NT 4.0',
					'winnt4.0'			=> 'Windows NT 4.0',
					'winnt 4.0'			=> 'Windows NT',
					'winnt'				=> 'Windows NT',
					'windows 98'		=> 'Windows 98',
					'win98'				=> 'Windows 98',
					'windows 95'		=> 'Windows 95',
					'win95'				=> 'Windows 95',
					'windows'			=> 'Unknown Windows OS',
					'os x'				=> 'Mac OS X',
					'ppc mac'			=> 'Power PC Mac',
					'freebsd'			=> 'FreeBSD',
					'ppc'				=> 'Macintosh',
					'linux'				=> 'Linux',
					'debian'			=> 'Debian',
					'sunos'				=> 'Sun Solaris',
					'beos'				=> 'BeOS',
					'apachebench'		=> 'ApacheBench',
					'aix'				=> 'AIX',
					'irix'				=> 'Irix',
					'osf'				=> 'DEC OSF',
					'hp-ux'				=> 'HP-UX',
					'netbsd'			=> 'NetBSD',
					'bsdi'				=> 'BSDi',
					'openbsd'			=> 'OpenBSD',
					'gnu'				=> 'GNU/Linux',
					'unix'				=> 'Unknown Unix OS'
				);


	// The order of this array should NOT be changed. Many browsers return
	// multiple browser types so we want to identify the sub-type first.
	var $browsers = array(
					'Opera'				=> 'Opera',
					'MSIE'				=> 'Internet Explorer',
					'Internet Explorer'	=> 'Internet Explorer',
					'Shiira'			=> 'Shiira',
					'Firefox'			=> 'Firefox',
					'Chimera'			=> 'Chimera',
					'Phoenix'			=> 'Phoenix',
					'Firebird'			=> 'Firebird',
					'Camino'			=> 'Camino',
					'Netscape'			=> 'Netscape',
					'OmniWeb'			=> 'OmniWeb',
					'Mozilla'			=> 'Mozilla',
					'Safari'			=> 'Safari',
					'Konqueror'			=> 'Konqueror',
					'icab'				=> 'iCab',
					'Lynx'				=> 'Lynx',
					'Links'				=> 'Links',
					'hotjava'			=> 'HotJava',
					'amaya'				=> 'Amaya',
					'IBrowse'			=> 'IBrowse'
				);

	var $mobiles = array(
					// legacy array, old values commented out
					'mobileexplorer'	=> 'Mobile Explorer',
//					'openwave'			=> 'Open Wave',
//					'opera mini'		=> 'Opera Mini',
//					'operamini'			=> 'Opera Mini',
//					'elaine'			=> 'Palm',
					'palmsource'		=> 'Palm',
//					'digital paths'		=> 'Palm',
//					'avantgo'			=> 'Avantgo',
//					'xiino'				=> 'Xiino',
					'palmscape'			=> 'Palmscape',
//					'nokia'				=> 'Nokia',
//					'ericsson'			=> 'Ericsson',
//					'blackberry'		=> 'BlackBerry',
//					'motorola'			=> 'Motorola'
					
					// Phones and Manufacturers
					'motorola'			=> "Motorola",
					'nokia'				=> "Nokia",
					'palm'				=> "Palm",
					'iphone'			=> "Apple iPhone",
					'ipod'				=> "Apple iPod Touch",
					'sony'				=> "Sony Ericsson",
					'ericsson'			=> "Sony Ericsson",
					'blackberry'		=> "BlackBerry",
					'cocoon'			=> "O2 Cocoon",
					'blazer'			=> "Treo",
					'lg'				=> "LG",
					'amoi'				=> "Amoi",
					'xda'				=> "XDA",
					'mda'				=> "MDA",
					'vario'				=> "Vario",
					'htc'				=> "HTC",
					'samsung'			=> "Samsung",
					'sharp'				=> "Sharp",
					'sie-'				=> "Siemens",
					'alcatel'			=> "Alcatel",
					'benq'				=> "BenQ",
					'ipaq'				=> "HP iPaq",
					'mot-'				=> "Motorola",
					'playstation portable' 	=> "PlayStation Portable",
					'hiptop'			=> "Danger Hiptop",
					'nec-'				=> "NEC",
					'panasonic'			=> "Panasonic",
					'philips'			=> "Philips",
					'sagem'				=> "Sagem",
					'sanyo'				=> "Sanyo",
					'spv'				=> "SPV",
					'zte'				=> "ZTE",
					'sendo'				=> "Sendo",
					
					// Operating Systems
					'symbian'				=> "Symbian",
					'elaine'				=> "Palm",
					'palm'					=> "Palm",
					'series60'				=> "Symbian S60",
					'windows ce'			=> "Windows CE",
				
					// Browsers	
					'obigo'					=> "Obigo",
					'netfront'				=> "Netfront Browser",
					'openwave'				=> "Openwave Browser",
					'mobilexplorer'			=> "Mobile Explorer",
					'operamini'				=> "Opera Mini",
					'opera mini'			=> "Opera Mini",
				
					// Other
					'digital paths'			=> "Digital Paths",
					'avantgo'				=> "AvantGo",
					'xiino'					=> "Xiino",
					'novarra'				=> "Novarra Transcoder",
					'vodafone'				=> "Vodafone",
					'docomo'				=> "NTT DoCoMo",
					'o2'					=> "O2",
				
					// Fallback
					'mobile'				=> "Generic Mobile",
					'wireless' 				=> "Generic Mobile",
					'j2me'					=> "Generic Mobile",
					'midp'					=> "Generic Mobile",
					'cldc'					=> "Generic Mobile",
					'up.link'				=> "Generic Mobile",
					'up.browser'			=> "Generic Mobile",
					'smartphone'			=> "Generic Mobile",
					'cellphone'				=> "Generic Mobile"
				);
	
	var $robots		= array();
	
	var $platform	= '';
	var $browser	= '';
	var $version	= '';
	var $mobile		= '';
	var $robot		= '';
	
	/**
	 * Singleton Pattern.
	 *
	 * @var object
	 **/
	private static $instance = NULL;

	// --------------------------------------------------------------------

	/**
	 * Implemento il Singleton.
	 *
	 * @return	object
	 */
	public static function get_instance()
	{
		if ( self::$instance == NULL )
		{   
			$c = __CLASS__;
		    self::$instance =& new $c;
		}
		
		return self::$instance;
	}

	// --------------------------------------------------------------------

	private function __construct(){}
	
	// --------------------------------------------------------------------

	private function __clone(){}
	
	// --------------------------------------------------------------------

	public function __destruct(){}
	
	// --------------------------------------------------------------------

	/**
	 * Implemento il Factory.
	 */
	public static function factory()
	{
		// Creo l'oggetto.
		$user_agent = self::get_instance();
		
		if ( isset($_SERVER['HTTP_USER_AGENT']) )
		{
			$user_agent->agent = trim($_SERVER['HTTP_USER_AGENT']);
		}
		
		if ( ! is_null($user_agent->agent) )
		{
			$user_agent->_compile_data();
		}
	}

	// --------------------------------------------------------------------
	
	/**
	 * Compile the User Agent Data
	 *
	 * @access	private
	 * @return	bool
	 */		
	function _compile_data()
	{
		$this->_set_platform();
	
		foreach ( array('_set_browser', '_set_robot', '_set_mobile') AS $function )
		{
			if ( $this->$function() === TRUE )
			{
				break;
			}
		}	
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Set the Platform
	 *
	 * @access	private
	 * @return	mixed
	 */		
	function _set_platform()
	{
		if ( is_array($this->platforms) AND count($this->platforms) > 0 )
		{
			foreach ( $this->platforms AS $key => $val )
			{
				if ( preg_match("|".preg_quote($key)."|i", $this->agent) )
				{
					$this->platform = $val;
					return TRUE;
				}
			}
		}
		$this->platform = lang('Unknown Platform');
	}

	// --------------------------------------------------------------------
	
	/**
	 * Set the Browser
	 *
	 * @access	private
	 * @return	bool
	 */		
	function _set_browser()
	{
		if ( is_array($this->browsers) AND count($this->browsers) > 0 )
		{
			foreach ( $this->browsers AS $key => $val )
			{		
				if ( preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match) )
				{
					$this->is_browser = TRUE;
					$this->version = $match[1];
					$this->browser = $val;
					$this->_set_mobile();
					return TRUE;
				}
			}
		}
		return FALSE;
	}
			
	// --------------------------------------------------------------------
	
	/**
	 * Set the Robot
	 *
	 * @access	private
	 * @return	bool
	 */		
	function _set_robot()
	{
		if ( is_array($this->robots) AND count($this->robots) > 0 )
		{		
			foreach ( $this->robots AS $key => $val )
			{
				if ( preg_match("|".preg_quote($key)."|i", $this->agent) )
				{
					$this->is_robot = TRUE;
					$this->robot = $val;
					return TRUE;
				}
			}
		}
		return FALSE;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Set the Mobile Device
	 *
	 * @access	private
	 * @return	bool
	 */		
	function _set_mobile()
	{
		if ( is_array($this->mobiles) AND count($this->mobiles) > 0 )
		{		
			foreach ( $this->mobiles AS $key => $val )
			{
				if ( FALSE !== (strpos(strtolower($this->agent), $key)) )
				{
					$this->is_mobile = TRUE;
					$this->mobile = $val;
					return TRUE;
				}
			}
		}	
		return FALSE;
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Set the accepted languages
	 *
	 * @access	private
	 * @return	void
	 */			
	function _set_languages()
	{
		if ( (count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '' )
		{
			$languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])));
			
			$this->languages = explode(',', $languages);
		}
		
		if ( count($this->languages) == 0 )
		{
			$this->languages = array('Undefined');
		}	
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Set the accepted character sets
	 *
	 * @access	private
	 * @return	void
	 */			
	function _set_charsets()
	{	
		if ( (count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '' )
		{
			$charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])));
			
			$this->charsets = explode(',', $charsets);
		}
		
		if ( count($this->charsets) == 0 )
		{
			$this->charsets = array('Undefined');
		}	
	}

	// --------------------------------------------------------------------
	
	/**
	 * Is Browser
	 *
	 * @return	bool
	 */		
	public static function is_browser()
	{
		return self::get_instance()->is_browser;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Is Robot
	 *
	 * @return	bool
	 */		
	public static function is_robot()
	{
		return self::get_instance()->is_robot;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Is Mobile
	 *
	 * @return	bool
	 */		
	public static function is_mobile()
	{
		return self::get_instance()->is_mobile;
	}	

	// --------------------------------------------------------------------
	
	/**
	 * Is this a referral from another site?
	 *
	 * @return	bool
	 */			
	public static function is_referral()
	{
		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Agent String
	 *
	 * @return	string
	 */			
	public static function agent_string()
	{
		return self::get_instance()->agent;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Get Platform
	 *
	 * @return	string
	 */			
	public static function platform()
	{
		return self::get_instance()->platform;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Get Browser Name
	 *
	 * @return	string
	 */			
	public static function browser()
	{
		return self::get_instance()->browser;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Get the Browser Version
	 *
	 * @return	string
	 */			
	public static function version()
	{
		return self::get_instance()->version;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Get The Robot Name
	 *
	 * @return	string
	 */				
	public static function robot()
	{
		return self::get_instance()->robot;
	}
	// --------------------------------------------------------------------
	
	/**
	 * Get the Mobile Device
	 *
	 * @return	string
	 */			
	public static function mobile()
	{
		return self::get_instance()->mobile;
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Get the referrer
	 *
	 * @return	bool
	 */			
	public static function referrer()
	{
		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']);
	}

	// --------------------------------------------------------------------
	
	/**
	 * Get the accepted languages
	 *
	 * @return	array
	 */			
	public static function languages()
	{
		// Creo l'oggetto.
		$user_agent = self::get_instance();
		
		if ( count($user_agent->languages) == 0 )
		{
			$user_agent->_set_languages();
		}
	
		return $user_agent->languages;
	}

	// --------------------------------------------------------------------
	
	/**
	 * Get the accepted Character Sets
	 *
	 * @return	array
	 */			
	public static function charsets()
	{
		// Creo l'oggetto.
		$user_agent = self::get_instance();
		
		if ( count($user_agent->charsets) == 0 )
		{
			$user_agent->_set_charsets();
		}
	
		return $user_agent->charsets;
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Test for a particular language
	 *
	 * @return	bool
	 */			
	public static function accept_lang($lang = 'en')
	{
		return ( in_array(strtolower($lang), self::languages(), TRUE) ) ? TRUE : FALSE;
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Test for a particular character set
	 *
	 * @return	bool
	 */			
	public static function accept_charset($charset = 'utf-8')
	{
		return ( in_array(strtolower($charset), self::charsets(), TRUE) ) ? TRUE : FALSE;
	}
	
	
}
